from django.db import models, transaction
from django.db.models import Value
from django.db.models.functions import Concat
from django.contrib.auth.models import AbstractUser
from django.core.validators import RegexValidator
from django.contrib.auth.models import UserManager as DefaultUserManager
from django.utils import timezone
from django.urls import reverse


SMS_REGEX_PATTERN = r"^1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4[579]\d{2})\d{6}$"
phone_number_validator = RegexValidator(
    SMS_REGEX_PATTERN, message="格式不正确，仅支持11位中国大陆手机号码"
)

class UserQuerySet(models.QuerySet):
    def cancel_users(self):
        """注销用户"""
        with transaction.atomic():
            postfix = str(int(timezone.now().timestamp()))
            if canceled_count := self.filter(is_active=False).count():
                raise Exception(
                    f"选择的用户有{canceled_count}位已经被注销，请勿重复注销"
                )
            self.filter().update(
                is_active=False,
                phone_number=None,
                username=Concat(Value("_canceled_"), "username", Value("_" + postfix)),
                nickname="[已注销]",
                real_name="[已注销]",
                avatar=None,
            )


class UserManager(DefaultUserManager.from_queryset(UserQuerySet)):
    use_in_migrations = True


class User(AbstractUser):
    phone_number = models.CharField(
        "手机号",
        max_length=11,
        unique=True,
        null=True,
        blank=False,
        validators=[phone_number_validator],
        error_messages={
            "unique": "手机号已被注册",
        },
        help_text="必填；仅支持11位中国大陆手机号码",
    )
    nickname = models.CharField("昵称", max_length=15, null=False, blank=True)
    avatar = models.ImageField(
        verbose_name="头像",
        upload_to="avatar/user",
        null=True,
        blank=True,
    )
    real_name = models.CharField(
        "姓名", max_length=15, null=False, blank=True
    )
    
    objects = UserManager()

    USERNAME_FIELD = "phone_number"
    REQUIRED_FIELDS = ["username"]

    def __str__(self):
        if self.nickname:
            return self.nickname
        elif self.username:
            return self.username
        elif self.real_name:
            return self.real_name
        else:
            return self.phone_number

    def get_absolute_url(self):
        """获取用户主页的URL，如果用户已注销则返回None"""
        if not self.is_active:
            return None
        return reverse('someones_post_list', kwargs={'user_id': self.id})


class InviteCode(models.Model):
    code = models.CharField("邀请码", max_length=6, unique=True)
    creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="created_invite_codes", verbose_name="创建者")
    used_by = models.OneToOneField(User, on_delete=models.SET_NULL, null=True, blank=True, related_name="used_invite_code", verbose_name="使用者")
    created_at = models.DateTimeField("创建时间", auto_now_add=True)
    used_at = models.DateTimeField("使用时间", null=True, blank=True)

    class Meta:
        verbose_name = "邀请码"
        verbose_name_plural = "邀请码"

    def __str__(self):
        return f"{self.code} - {self.creator.nickname or self.creator.username}"